package com.cl.security.base.service;

import com.cl.security.common.result.CommonResult;
import com.cl.security.base.repository.BaseRepository;
import com.cl.security.common.util.FieldUtil;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.jpa.domain.Specification;

import javax.persistence.criteria.Predicate;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;


public abstract class BaseService<Entity,Repository extends BaseRepository<Entity>>{
    private final Repository repository;

    protected BaseService(Repository repository) {
        this.repository = repository;
    }

    public CommonResult save(Entity entity) {
        return CommonResult.success(repository.save(entity));
    }
    public CommonResult saveAll(List<Entity> entities) {
            if (((boolean) FieldUtil.getFieldValueByName("deleted", entities.get(0)))) {
              repository.deleteAll(entities);
              return CommonResult.success("删除成功");
            }
        return CommonResult.success(repository.saveAll(entities));
    }
    public CommonResult list() {
        return CommonResult.success(repository.findAll());
    }
    public CommonResult page(int pageNumber, int pageSize, Entity entity) {
        return CommonResult.success(repository.findAll((Specification<Entity>) (root, criteriaQuery, criteriaBuilder) -> {
            List<Predicate> predicateList = new ArrayList<>();
            List<Map<String,Object>> fieldList = FieldUtil.getFiledsInfo(entity);
            fieldList.stream().filter(field-> field.get("value")!=null ).forEach(field->{
                String name = field.get("name").toString();
                Object value = field.get("value");
                Class<?> type = (Class<?>) field.get("type");
                if (!Collection.class.isAssignableFrom(type) && !type.cast(value).toString().isEmpty()) {
                    if (String.class.isAssignableFrom(type)) {
                        predicateList.add(criteriaBuilder.like(root.get(name), "%" + value + "%"));
                    }else {
                        predicateList.add(criteriaBuilder.equal(root.get(name),type.cast(value)));
                    }
                }

            });
            return criteriaQuery.where(predicateList.toArray(new Predicate[predicateList.size()])).getRestriction();
        }, PageRequest.of(pageNumber - 1, pageSize)));
    }


}
